Unit Comptes;

Interface
TYPE
	//concerne les données d'un compte
		Tcompte=RECORD
			IDcompte:INTEGER;
			Libelle:STRING;
			taux:REAL;
			solde:DOUBLE;
			limite:DOUBLE;
		END;
		//concerne le tableau ou sont stocke les comptes
		TTabCompte=RECORD
			compteclient:ARRAY[1..100] of Tcompte;
			nbcompte:INTEGER;
		END;
		
// Creation d'un nouveau compte pour un client déjà spécifié
Procedure creationCompte(VAR tabCompte : TTabCompte;VAR DernierIDCompte:INTEGER );

// Procedure add compte
Procedure addCompte(VAR TabCompte:TTabCompte;VAR LastID:INTEGER;libelle:STRING;taux:REAL;solde:DOUBLE;limite:DOUBLE);

// Insere le compte dans la tabcompte
Procedure enrCompte(compte : Tcompte; VAR tabcompte : TTabCompte);

// Function qui recherche le compte par son ID, retourne -1 si il n'existe pas	
Function indiceCompte(ID_compte:INTEGER ; tabcompte : TTabCompte) : INTEGER;
	
// Procedure crediter compte
Procedure credit(VAR compte:Tcompte;montant:DOUBLE);
	
// Procedure debiter compte
Procedure debit(VAR compte:Tcompte;montant:DOUBLE);
		
// Procedure qui demande le montant et l'ajoute au compte
Procedure depot (VAR tabcompte : TCompte);

// Procedure qui demande le montant et le déduit du compte si les fonds le permettent
Procedure retrait(VAR tabcompte : TCompte);

// Procedure qui solde le compte et le ferme
Procedure cloture(ID_Compte : INTEGER ; VAR tabcompte : TTabCompte);

// Procedure qui affiche le compte
PROCEDURE afficherCompte(compte : TCompte);

// Procedure qui affiche tous les comptes
PROCEDURE afficherComptes(tabcompte : TTabCompte);
	
// Function Permet de calculer la fortune d'une collection de compte	
Function  Fortune(tabcompte:TTabCompte):DOUBLE;	
	
// Function Selection compte client
Function selectCompte(tabcompte:TTabCompte):INTEGER;

// Fonction qui test la solvabilité du compte
Function testSolvabilite(compte:Tcompte;montant:DOUBLE):BOOLEAN;

// Procedure bouclement du compte client
Procedure bouclementCompte(VAR compte:TCompte;jours:INTEGER);
		
implementation

// ajoute un compte dans notre collection
procedure addCompte(VAR tabCompte:TTabCompte;compte:TCompte;VAR DernierIDCompte:INTEGER);
	Begin
		tabCompte.nbcompte += 1;
		DernierIDCompte += 1;
		compte.IDCompte := DernierIDCompte;
		tabCompte.compteclient[tabCompte.nbcompte]:=compte;
	End;
	
// Creation d'un nouveau compte pour un client déjà spécifié	
Procedure  creationCompte(VAR tabCompte : TTabCompte;VAR DernierIDCompte:INTEGER );
	
	VAR 
	compte : Tcompte;
	choixTaux : STRING;
	choixType : STRING;
BEGIN
	//initialise compte
	compte.libelle:='';
	compte.taux:=0;
	compte.solde:=-1;
	compte.limite:=1;
																				
	// Choix Type Compte
	WHILE(compte.libelle = '') DO
		BEGIN		
			WRITELN('Entrez le type de compte : ');
			WRITELN('1. Courant');
			WRITELN('2. Epargne');
			WRITELN('');
			WRITE('Entrer votre choix : ');
			READLN (choixType);
			WRITELN('');
			CASE (choixType) OF
					'1':
						begin
							compte.Libelle := 'Courant';
						end;
					'2':
						begin
							compte.Libelle := 'Epargne';
						end;
			end;
		End;
	// Definition du taux d'interet
	WHILE(compte.taux = 0) DO
	BEGIN	
		WRITELN('Entrez le taux du compte : ');
		WRITELN('1. 0.5%');
		WRITELN('2. 1.5%');
		WRITELN('3. 2.5%');
		WRITELN('4. 5%');
		WRITELN('');
		WRITE('Entrer votre choix : ');
		READLN(choixTaux);
		WRITELN('');
		CASE (choixTaux) OF
				'1':
					begin
						compte.taux := 0.5;
					end;
				'2':
					begin
						compte.taux := 1.5;
					end;
				'3':
					begin
						compte.taux := 2.5;
					end;
				'4':
					begin
						compte.taux := 5.0;
					end;
		end;
		
	END;
	//Définition du solde initial	
	WHILE(compte.solde = -1) DO
		BEGIN
			WRITE('Entrez le solde initiale du compte : ');										
			READLN(compte.solde);
			WRITELN('');
			IF (compte.solde = -1) THEN
				WRITELN('Il est obligatoire de saisir un solde!');
		END;
																			
	//Définition de la limite négative
	WHILE(compte.limite = 1) DO																	
		BEGIN		
			WRITE('Entrez la limite de retrait du compte (ex. -500): ');
			READLN(compte.limite);
			WRITELN('');
			IF (compte.limite = 1) THEN
				WRITELN('Il est obligatoire de saisir une limite!');
		END;	
	addCompte(tabcompte, compte,DernierIDCompte);
END; // Fin procedure creationCompte	

//Procedure qui ajoute un compte en genant l'ID
Procedure addCompte(VAR tabCompte:TTabCompte;VAR LastID:INTEGER;libelle:STRING;taux:REAL;solde:DOUBLE;limite:DOUBLE);
	Begin
		LastID += 1;
		tabCompte.nbCompte += 1;
		tabCompte.compteClient[tabCompte.nbCompte].IDcompte:=LastID;
		tabCompte.compteClient[tabCompte.nbCompte].libelle:=libelle;
		tabCompte.compteClient[tabCompte.nbCompte].taux:=taux;
		tabCompte.compteClient[tabCompte.nbCompte].solde:=solde;	
		tabCompte.compteClient[tabCompte.nbCompte].limite:=limite;	
	End; // Fin AddCompte
														

//Insere le compte dans la tabcompte
Procedure enrCompte(compte : Tcompte; VAR tabcompte : TTabCompte);	
	VAR
		choix: STRING;

	//On appelle l'enregistrement dans la fonction qui crée ou modifie un compte
	BEGIN		
		WRITE('Voulez-vous enregistrer le compte: o / n : '); 
		READ(choix);
		IF(choix = 'o') THEN
			BEGIN
				tabcompte.compteclient[tabcompte.nbcompte+1]:=compte;	 
				tabcompte.nbcompte:=tabcompte.nbcompte+1;			 	
			END;
	END; // Fin procedure enrCompte

// Function qui recherche le compte par son ID, retourne -1 si il n'existe pas	
Function indiceCompte(ID_compte:INTEGER ; tabcompte : TTabCompte) : INTEGER;
	Var
		i:INTEGER;
	Begin
		i:=1;
		WHILE( i <= tabcompte.nbcompte) AND (ID_compte <> tabcompte.compteclient[i].IDcompte) DO
			begin
				i:=i + 1;
			end;																			
		IF(i > tabcompte.nbcompte) THEN
			i:=-1;	// Compte pas trouvé retourne -1																			
		indiceCompte:=i;																		
	END; // Fin fonction indiceCompte
	
// Procedure crediter compte
Procedure credit(VAR compte:Tcompte;montant:DOUBLE);
	Begin
		//Modification et affichage du solde
		compte.solde:= compte.solde + montant;
		WRITELN('Nouveau solde compte Numero ',compte.IDCompte,' : ',compte.solde:0:2);	
		WRITELN('');
	End; // Fin rocedure credit
	
// Procedure debiter compte
Procedure debit(VAR compte:Tcompte;montant:DOUBLE);
	Begin
		//Modification et affichage du solde
		compte.solde:= compte.solde - montant;
		WRITELN('Nouveau solde compte Numero ',compte.IDCompte,' : ',compte.solde:0:2);	
		WRITELN('');
	End; // Fin rocedure credit
	
// Procedure qui demande le montant et l'ajoute au compte
Procedure depot (VAR tabcompte : TCompte);						 
	Var
		montant: DOUBLE;
		
	BEGIN 	    											
		WRITE('Entrer le montant a deposer : ');
		READLN(montant);
		credit(tabcompte,montant);						
	END; // Fin procedure depot

// Procedure qui demande le montant et le déduit du compte si les fonds le permettent
Procedure retrait(VAR tabcompte : TCompte)	;						
	Var
		montant: DOUBLE;
		
	BEGIN  															
		WRITE('Entrer le montant desirer a retirer : ');
		READLN(montant);
		IF(testSolvabilite(tabcompte,montant)) THEN
				debit(tabcompte,montant); 
	END; // Fin proceure retrait


// Procedure qui solde le compte et le ferme	
Procedure cloture(ID_Compte : INTEGER ; VAR tabcompte : TTabCompte);					
	Var
		i :	INTEGER;
		choix : STRING;
		
	Begin
			i := ID_Compte;	
			WRITE('Confirmez la suppression du compte ? o/n : ');
			READ(choix);				
			IF(choix ='o') THEN
				begin										
					WHILE (i<=tabcompte.nbcompte) DO
						begin
							//le compte a supprimé est ecrase par le suivant 
							tabcompte.compteclient[i]:= tabcompte.compteclient[i+1];
							i:=i+1;
						end;
					tabcompte.nbcompte := tabcompte.nbcompte - 1;
					WRITELN('Le compte a ete supprime');
				end
	END; // Fin Procedure cloture 

// Procedure qui affiche le compte
PROCEDURE afficherCompte(compte : TCompte);
	BEGIN
		WRITELN('---------------------------------------------------');
		WRITELN('Numero de compte:  ', compte.IDcompte);
		WRITELN('Libelle:           ', compte.Libelle);
		WRITELN('Taux:              ', compte.taux:0:1,'%');
		WRITELN('Solde:             ',compte.solde:0:2); // :0:2 Permet de formatter l'affichage
		WRITELN('Limite de retrait: ',compte.limite:0:0);
		WRITELN('---------------------------------------------------');
		WRITELN('');				
	END; // Fin procedure afficheCompte
	
PROCEDURE afficherComptes(tabcompte : TTabCompte);
	VAR
		i : INTEGER;
	BEGIN
	
		i := 1;
		WHILE (i <= tabcompte.nbcompte) DO
		BEGIN
			WRITELN('Indice N ',i);
			afficherCompte(tabcompte.compteclient[i]);
			i := i + 1;
		END;
	END; // Fin procedure afficherComptes
	
//Permet de calculer la fortune d'une collection de compte	
Function  Fortune(tabcompte:TTabCompte):DOUBLE;	
	VAR
		i:INTEGER;
	BEGIN
		i:=1;
		Fortune:=0;
		WHILE(i<=tabcompte.nbcompte) DO
			BEGIN
			Fortune += tabcompte.compteclient[i].solde;		
			i+=1;	
			END;
	END; // Fin Function Fortune
	
// Function Selection compte client
Function selectCompte(tabcompte:TTabCompte):INTEGER;
	Var
		indiceCo:INTEGER;
	BEGIN
		WRITELN('');
		afficherComptes(tabcompte);
		WRITELN('');
		WRITE('Selection Compte (Entrer l''indice): ');
		READLN(indiceCo);
		WHILE (indiceCo < 0) OR (indiceCo > tabcompte.nbCompte) DO
			Begin
				WRITELN('Compte inexistant');
				WRITELN('');
				WRITE('Entrez un numero de compte correcte: ');
				READLN(indiceCo);
			END;
		selectCompte:=indiceCo;
	END;

// Fonction qui test la solvabilité du compte
Function testSolvabilite(compte:Tcompte;montant:DOUBLE):BOOLEAN;
	Begin
		IF((compte.solde - montant) < compte.limite) THEN
			Begin
				WRITELN('Votre solde est de ',compte.solde:0:2, ' transaction impossible');
				WRITELN('');
				WRITELN('Votre decouvert maximum est de ',compte.limite:0:2);
				testSolvabilite:=FALSE;
			End
		 else
			testSolvabilite:=TRUE;
	End;
	
// Procedure bouclement annuel du compte client
Procedure bouclementCompte(VAR compte:TCompte;jours:INTEGER);
	Var
		interet:DOUBLE;
	Begin
		interet:=compte.solde/100*compte.taux*(jours/360);
		credit(compte,interet);	
	End; // Fin bouclementAnnuelComptes
end.
